package cn.sprouting.tool;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;

import java.util.*;

/**
 * @author ：LX
 * @ Date 创建时间： 2021/10/27. 1:41
 * 地点：长沙麓谷
 * 目的: 网络相关
 * 备注说明：
 */
public class RandomNetworkTool {

    /**
     * 网络地址后缀
     */
    private static final String[] URL_SUFFIX = ".com,.cn,.gov,.edu,.net,.org,.int,.mil,.biz,.info".split(",");


    /**
     * 根据CIDR生成一个随机的IP地址
     * @param cidr cidr
     * @return 一个符合这个CIDR的IP地址
     */
    public String getIpByCidr(String cidr){
        Random random = new Random();
        // 解析CIDR
        String[] parts = cidr.split("/");
        String ipPart = parts[0];
        int prefixLength = Integer.parseInt(parts[1]);

        // 将IP地址转换成整数形式
        String[] ipParts = ipPart.split("\\.");
        int ip = (Integer.parseInt(ipParts[0]) << 24) |
                (Integer.parseInt(ipParts[1]) << 16) |
                (Integer.parseInt(ipParts[2]) << 8) |
                Integer.parseInt(ipParts[3]);

        // 计算可用的IP范围
        int range = 32 - prefixLength;
        int startIP = ip & ((-1 << range) & 0xFFFFFFFF);
        int endIP = startIP | ((1 << range) - 1);

        // 生成随机IP地址
        int randomIPInt = random.nextInt(endIP - startIP + 1) + startIP;

        // 转换为字符串形式
        return ((randomIPInt >> 24) & 0xFF) + "." +
                ((randomIPInt >> 16) & 0xFF) + "." +
                ((randomIPInt >> 8) & 0xFF) + "." +
                (randomIPInt & 0xFF);
    }

    /**
     * 随机生成一个CIDR
     * @return
     */
    public String getCidr(){
        int first;
        int second;
        int third;
        int fourth;
        int prefixLength;

        Random random = new Random();
        // 随机选择私有地址段或公共地址段
        int addressType = random.nextInt(3);
        switch (addressType) {
            case 0:
                // 生成私有地址段，如 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
                first = 10;
                second = random.nextInt(256);
                third = random.nextInt(256);
                fourth = 0;
                // 8到16之间的前缀长度
                prefixLength = random.nextInt(9) + 8;
                break;
            case 1:
                first = 172;
                // 16到31之间
                second = random.nextInt(16) + 16;
                third = random.nextInt(256);
                fourth = 0;
                // 12到24之间的前缀长度
                prefixLength = random.nextInt(13) + 12;
                break;
            case 2:
                // 生成公共地址段，排除保留地址段
                do {
                    // 0到223之间
                    first = random.nextInt(224);
                } while (first == 0 || first == 10 || first == 127 || (first >= 224 && first <= 239));
                second = random.nextInt(256);
                third = random.nextInt(256);
                fourth = random.nextInt(256);
                // 8到32之间的前缀长度
                prefixLength = random.nextInt(25) + 8;
                break;
            default:
                throw new IllegalStateException("意外的生成数据: " + addressType);
        }

        // 构造CIDR格式字符串
        return first + "." + second + "." + third + "." + fourth + "/" + prefixLength;
    }

    /**
     * 随机生成URL地址
     * @param num 生成数量
     * @param min 网址最小长度，不能低于 3
     * @param max 网络最大长度，不能低于 4
     * @param suffixList 后缀，常用比如 .com .cn ，不指定则使用默认
     * @param prefix 前缀，常用有 https:// http:// ，默认使用 http://
     * @return
     */
    public List<String> getUrl(Integer num, int min, int max, List<String> suffixList, String prefix){
        if (num == null || num < 1){
            num = 1;
        }
        if (min < 3){
            min = 3;
        }
        if (max < 4){
            max = 4;
        }

        if (suffixList == null || suffixList.size() == 0){
            suffixList = Arrays.asList(URL_SUFFIX);
        }
        if (StrUtil.isEmpty(prefix)){
            prefix = "http://";
        }

        List<String> saveList = new ArrayList<>();
        for (int i = 0; i < num; i ++){
            int length = RandomUtil.randomInt(min, max);
            String str = RandomUtil.randomString(RandomUtil.BASE_CHAR, length).toUpperCase();
            String url = prefix + RandomUtil.randomEle(suffixList) + str;
            saveList.add(url);
        }

        return saveList;
    }

    /**
     * 随机生成URL地址
     * @param num 生成数量
     * @param suffixList 后缀，常用比如 .com .cn ，不指定则使用默认
     * @param prefix 前缀，常用有 https:// http:// ，默认使用 http://
     * @return
     */
    public List<String> getUrl(Integer num, List<String> suffixList, String prefix){
        return getUrl(num, 3, 10, suffixList, prefix);
    }

    /**
     * 随机生成URL地址
     * @param num 生成数量
     * @return
     */
    public List<String> getUrl(Integer num){
        return getUrl(num, 3, 10, null, null);
    }

    /**
     * 随机生成URL地址
     * @return
     */
    public String getUrl(){
        return getUrl(1, 3, 10, null, null).get(0);
    }

    /**
     * 随机生成公网的IPV4地址
     * @param num 生成数量
     * @return
     */
    public static List<String> getIpv4(Integer num){
        String adultCollegesAndUniversities = ResourceUtil.readUtf8Str("chineseIp.txt");
        String[] array = adultCollegesAndUniversities.split("\r\n");

        // 起始IP地址
        String startIp = "startIp";
        // 结束IP
        String endIp = "endIp";

        // 读取IP并转换
        List<Map<String, Long>> list = new ArrayList<>();
        for (String str : array){
            ArrayList<String> row = CollUtil.newArrayList(str.split(","));

            Map<String, Long> map = new HashMap<>();
            map.put(startIp, ipv4ToLong(row.get(0)));
            map.put(endIp, ipv4ToLong(row.get(1)));
            list.add(map);
        }


        if (num == null || num < 1){
            num = 1;
        }

        List<String> saveList = new ArrayList<>();
        for (int i = 0; i < num; i ++){
            // 随机出一个IP范围
            Map<String, Long> stringLongMap = RandomUtil.randomEle(list);
            long ipv4 = RandomUtil.randomLong(stringLongMap.get(startIp), stringLongMap.get(endIp));
            saveList.add(longToIpv4(ipv4));
        }

        return saveList;
    }

    /**
     * 随机生成公网的IPV4地址
     * @return
     */
    public static String getIpv4(){
        return getIpv4(1).get(0);
    }

    /**
     * 随机生成内网的IPV4地址
     * @param num 生成数量
     * @return
     */
    public static List<String> getPrivateIpv4(Integer num){
        List<String> saveList = new ArrayList<>();
        for (int i = 0; i < num; i ++){
            int index = RandomUtil.randomInt(1, 101);
            if (index % 2 == 0){
                saveList.add("10." + RandomUtil.randomInt(0, 256) + "." + RandomUtil.randomInt(0, 256) + "." + RandomUtil.randomInt(0, 256));
            } else if (index % 3 == 0){
                saveList.add("172." + RandomUtil.randomInt(16, 32) + "." + RandomUtil.randomInt(0, 256) + "." + RandomUtil.randomInt(0, 256));
            } else {
                saveList.add("192.168." + RandomUtil.randomInt(0, 256) + "." + RandomUtil.randomInt(0, 256));
            }
        }

        return saveList;
    }

    /**
     * 随机MAC地址
     * @return 随机MAC地址
     */
    public static String randomMacAddress() {
        int count = 6;
        List<String> mac = new ArrayList<>(count);

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < count; i++) {
            int n = RandomUtil.randomInt(0, 255);
            sb.append(String.format("%02x", n));
            if (i != 5){
                sb.append("-");
            }
        }

        return sb.toString().toUpperCase();
    }

    /**
     * 随机生成端口，注意，不会生成 1024 以下的端口号
     * @return
     */
    public static int getPort(){
        return RandomUtil.randomInt(1025, 65535);
    }

    /**
     * 随机生成 IPV6地址
     * @return
     */
    public static String getIpv6(){
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 8; i ++){
            sb.append(Integer.toHexString(RandomUtil.randomInt(0, 65535)));
            if (i != 7){
                sb.append(":");
            }
        }

        return sb.toString();
    }

    /**
     * 随机生成QQ号
     * @return
     */
    public static String getQQ(){
        // QQ号码最短5位，最长11位
        return RandomUtil.randomLong(10000L, 100000000000L) + "";
    }

    /**
     * IPv4地址转整数
     *
     * @param ipv4 IPv4地址
     * @return 整数
     */
    private static long ipv4ToLong(String ipv4) {
        String[] part = ipv4.split("\\.");
        long num = 0;
        for (int i = 0; i < part.length; i++) {
            int power = 3 - i;
            num += ((Integer.parseInt(part[i]) % 256 * Math.pow(256, power)));
        }
        return num;
    }

    /**
     * 整数转IPv4地址
     *
     * @param ipv4Num 整数
     * @return IPv4地址
     */
    private static String longToIpv4(long ipv4Num) {
        StringBuilder result = new StringBuilder(15);
        for (int i = 0; i < 4; i++) {
            result.insert(0, (ipv4Num & 0xff));
            if (i < 3) {
                result.insert(0, '.');
            }
            ipv4Num = ipv4Num >> 8;
        }
        return result.toString();
    }

}
